package com.example.demo33.service;

import com.example.demo33.entity.Data;
import com.example.demo33.entity.PriceBatchResponse;
import com.example.demo33.entity.PriceInfo;
import com.example.demo33.entity.SingleGoodResponse;
import com.example.demo33.entity.api.GoodIdResponse;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class CsqaqApiService {

    @Value("${csqaq.api.base-url}")
    private String apiBaseUrl;

    @Value("${csqaq.api.token}")
    private String apiToken;

    @Value("${csqaq.cache.max-size:1000}")
    private long cacheMaxSize;

    @Value("${csqaq.cache.expire-minutes:5}")
    private long cacheExpireMinutes;

    @Autowired
    private RestTemplate restTemplate;

    private Cache<String, Double> priceCache;



    @PostConstruct
    public void init() {
        priceCache = CacheBuilder.newBuilder()
                .maximumSize(cacheMaxSize)
                .expireAfterWrite(cacheExpireMinutes, TimeUnit.MINUTES)
                .build();
    }

    // 原有方法保持不变
    public GoodIdResponse getGoodId(Integer pageIndex, Integer pageSize, String search) {
        try {
            String url = apiBaseUrl + "/api/v1/info/get_good_id";
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("ApiToken", apiToken);

            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("page_index", pageIndex);
            requestBody.put("page_size", pageSize);
            if (search != null && !search.trim().isEmpty()) {
                requestBody.put("search", search.trim());
            }

            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<GoodIdResponse> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    requestEntity,
                    GoodIdResponse.class
            );

            if (response.getStatusCode() == HttpStatus.OK) {
                GoodIdResponse goodIdResponse = response.getBody();
                if (goodIdResponse != null && goodIdResponse.getCode() == 200) {
                    return goodIdResponse;
                } else {
                    throw new RuntimeException("API返回错误：" + (goodIdResponse != null ? goodIdResponse.getMsg() : "未知错误"));
                }
            } else {
                throw new RuntimeException("请求失败，状态码：" + response.getStatusCodeValue());
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("获取饰品ID信息失败：" + e.getMessage());
        }
    }

    // 原有方法保持不变
    public SingleGoodResponse getSingleGood(Integer goodId) {
        try {
            String url = apiBaseUrl + "/api/v1/info/good?id=" + goodId;
            HttpHeaders headers = new HttpHeaders();
            headers.set("ApiToken", apiToken);
            HttpEntity<Void> requestEntity = new HttpEntity<>(headers);

            ResponseEntity<SingleGoodResponse> response = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    requestEntity,
                    SingleGoodResponse.class
            );

            if (response.getStatusCode() == HttpStatus.OK) {
                SingleGoodResponse goodResponse = response.getBody();
                if (goodResponse != null && goodResponse.getCode() == 200) {
                    return goodResponse;
                } else {
                    throw new RuntimeException("API返回错误：" +
                            (goodResponse != null ? goodResponse.getMsg() : "未知错误"));
                }
            } else {
                throw new RuntimeException("请求失败，状态码：" + response.getStatusCodeValue());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("获取饰品详情失败：" + e.getMessage());
        }
    }





    // 优化后的批量获取饰品价格的方法
    public PriceBatchResponse getBatchPrices(List<String> marketHashNames) {
        // 结果Map，用于合并缓存数据和API返回数据
        Map<String, PriceInfo> mergedResult = new HashMap<>();
        // 需要从API获取的名称列表
        List<String> namesToFetch = new ArrayList<>();

        // 1. 先从缓存中获取已有的价格
        for (String name : marketHashNames) {
            Double cachedPrice = priceCache.getIfPresent(name);
            if (cachedPrice != null) {
                PriceInfo cachedInfo = new PriceInfo();
                cachedInfo.setMarketHashName(name);
                cachedInfo.setYyypSellPrice(cachedPrice);
                mergedResult.put(name, cachedInfo);
            } else {
                namesToFetch.add(name);
            }
        }

        // 2. 如果有需要从API获取的数据，则调用API
        if (!namesToFetch.isEmpty()) {
            try {
                String url = apiBaseUrl + "/api/v1/goods/getPriceByMarketHashName";
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headers.set("ApiToken", apiToken);

                Map<String, List<String>> requestBody = new HashMap<>();
                requestBody.put("marketHashNameList", namesToFetch);

                HttpEntity<Map<String, List<String>>> requestEntity = new HttpEntity<>(requestBody, headers);
                ResponseEntity<PriceBatchResponse> response = restTemplate.exchange(
                        url,
                        HttpMethod.POST,
                        requestEntity,
                        PriceBatchResponse.class
                );

                if (response.getStatusCode() == HttpStatus.OK) {
                    PriceBatchResponse priceResponse = response.getBody();
                    if (priceResponse != null && priceResponse.getCode() == 200) {
                        // 更新缓存并合并结果
                        if (priceResponse.getData() != null && priceResponse.getData().getSuccess() != null) {
                            for (Map.Entry<String, PriceInfo> entry : priceResponse.getData().getSuccess().entrySet()) {
                                PriceInfo item = entry.getValue();
                                if (item.getMarketHashName() != null && item.getYyypSellPrice() != null) {
                                    priceCache.put(item.getMarketHashName(), item.getYyypSellPrice());
                                    mergedResult.put(item.getMarketHashName(), item);
                                }
                            }
                        }
                    } else {
                        throw new RuntimeException("API返回错误：" +
                                (priceResponse != null ? priceResponse.getMsg() : "未知错误"));
                    }
                } else {
                    throw new RuntimeException("请求失败，状态码：" + response.getStatusCodeValue());
                }
            } catch (Exception e) {
                e.printStackTrace();
                // 发生异常时，只返回缓存中已有的数据
                PriceBatchResponse partialResponse = new PriceBatchResponse();
                partialResponse.setCode(206); // 206表示部分内容
                partialResponse.setMsg("部分数据来自缓存，部分获取失败：" + e.getMessage());

                Data data = new Data();
                data.setSuccess(mergedResult);
                data.setError(Collections.singletonList(e.getMessage()));
                partialResponse.setData(data);

                return partialResponse;
            }
        }

        // 3. 构建最终响应对象
        PriceBatchResponse finalResponse = new PriceBatchResponse();
        finalResponse.setCode(200);
        finalResponse.setMsg("操作成功");

        // 使用外部的 Data 类创建实例
        Data data = new Data();
        data.setSuccess(mergedResult);
        data.setError(Collections.emptyList()); // 设置空错误列表

        finalResponse.setData(data);
        return finalResponse;
    }


}